package poxer

/**
 * Parses the when/then definitions and handles matching against
 * actual requests.
 *
 * @author jleslie
 */
public class DefParser {

    // url -> method -> params
    // url -> * -> params
    // url -> method
    // url -> *
    // url

    private Map urls = new HashMap();
    private String otherwise;

    def parseUrl = { urlStr ->
        return urlStr.split(/\?/)[0]
    }

    def parseQueryParams = { urlStr ->
        def params = new TreeMap();

        def qstr = urlStr.split(/\?/)

        if (qstr.length > 1) {
            println qstr[1]
            qstr[1].split(/\&/).each() {
                def keyVal = it.split(/\=/)
                params.put(keyVal[0], keyVal[1])
            }
        }
        return params
    }

	def parse = { defs ->
        defs.each {
            if (it.otherwise) {
                otherwise = it.otherwise
            } else {
                 def req = [
                    url: parseUrl(it.when),
                    params: parseQueryParams(it.when)
                ]
                def params = req.params;
                if (!params) {
                     params = '*'
                }
                def method = req.method;
                if (!method) {
                    method = '*'
                }

                if (!urls.containsKey(req.url)) {
                    urls.put(req.url, new HashMap())
                }
                def meth = urls.get(req.url);
                if (!meth.containsKey(method)) {
                    meth.put(method, new HashMap())
                }

                def prm = meth.get(method)
                if (!prm.containsKey(params)) {
                    prm.put(params, it.then)
                }
            }
        }
    }

    def lastRequest;

    def find = { reqStr ->

        def req = [
            url: parseUrl(reqStr),
            params: parseQueryParams(reqStr)
        ]
        lastRequest = req;
        def xml = urls.get(req.url)?.get('*')?.get(req.params ? req.params : '*')
        println "Responding to ${reqStr},\nxml>\n${xml}\notherwise>\n${otherwise}"
        return (xml ? xml : otherwise)
    }
}

